package com.ruyuan.seckilling.activity.controller;

import com.ruyuan.dependency.product.api.ProductApi;
import com.ruyuan.dependency.product.vo.SkuVo;
import com.ruyuan.seckilling.activity.constant.ActivityStatusVal;
import com.ruyuan.seckilling.activity.entity.Activity;
import com.ruyuan.seckilling.activity.entity.ActivitySkuRef;
import com.ruyuan.seckilling.activity.request.ActivitySkuRefModifyRequest;
import com.ruyuan.seckilling.activity.request.ActivitySkuRefSaveRequest;
import com.ruyuan.seckilling.activity.service.ActivityService;
import com.ruyuan.seckilling.activity.service.ActivitySkuRefService;
import com.ruyuan.seckilling.common.MapResult;
import com.ruyuan.seckilling.inventory.api.InventoryApi;
import com.ruyuan.seckilling.inventory.vo.ProductStockVo;
import com.ruyuan.seckilling.inventory.vo.QueryCurrentStockRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhonghuashishan
 */
@Slf4j
@RestController
@RequestMapping("/activity/skuRef")
public class ActivitySkuRefController {

    @Autowired
    private ActivityService activityService;

    @Autowired
    private ActivitySkuRefService activitySkuRefService;

    @Autowired
    private ProductApi productApi;

    @Autowired
    private InventoryApi inventoryApi;

    /**
     * 根据活动id查询活动下的所有商品
     */
    @GetMapping("/queryByActivityId/{activityId}")
    public MapResult queryByActivityId(@PathVariable("activityId") Long activityId) {
        if (Objects.isNull(activityId) || activityId <= 0) {
            return MapResult.errorResult().setInfo("参数不合法");
        }

        List<ActivitySkuRef> activitySkuRefs = activitySkuRefService.queryByActivityId(activityId);
        if (CollectionUtils.isEmpty(activitySkuRefs)) {
            return MapResult.successResult().set("dataList", Collections.emptyList());
        }

        List<Long> skuIds = activitySkuRefs.stream().map(ActivitySkuRef::getSkuId).collect(Collectors.toList());

        // 调用商品服务查询商品信息
        List<SkuVo> skuVos = productApi.queryBySkuIds(skuIds);

        // 调用秒杀库存服务查询实时库存
        Activity activity = activityService.queryById(activityId);
        List<ProductStockVo> detailStocks = Collections.emptyList();
        Map<Long, ProductStockVo> skuIdDetailStockMap = Collections.emptyMap();
        Date now = new Date();
        if (now.after(activity.getStartTime()) && now.before(DateUtils.addHours(activity.getEndTime(), 1))) {
            detailStocks = inventoryApi.queryCurrentStock(new QueryCurrentStockRequest(activityId, skuIds));
            skuIdDetailStockMap = detailStocks.stream().collect(
                    Collectors.toMap(ProductStockVo::getSkuId, e -> e, (e1, e2) -> e1));
        }

        Map<Long, SkuVo> skuIdSkuVoMap = skuVos.stream().collect(Collectors.toMap(SkuVo::getId, e -> e, (e1, e2) -> e1));

        List<Object> dataList = new ArrayList<>();
        for (ActivitySkuRef activitySkuRef : activitySkuRefs) {
            Map<String, Object> map = new LinkedHashMap<>();
            Long skuId = activitySkuRef.getSkuId();
            map.put("skuId", skuId);
            map.put("salableStock", Optional.ofNullable(skuIdDetailStockMap.get(skuId))
                    .map(ProductStockVo::getSalableStock).orElse(activitySkuRef.getSalableStock()));
            map.put("lockedStock", Optional.ofNullable(skuIdDetailStockMap.get(skuId))
                    .map(ProductStockVo::getLockedStock).orElse(activitySkuRef.getLockedStock()));
            map.put("saledStock", Optional.ofNullable(skuIdDetailStockMap.get(skuId))
                    .map(ProductStockVo::getSaledStock).orElse(activitySkuRef.getSaledStock()));
            map.put("skuInfo", skuIdSkuVoMap.get(skuId));
            dataList.add(map);
        }
        return MapResult.successResult().set("dataList", dataList);
    }

    /**
     * 给活动添加一个秒杀商品
     */
    @PostMapping("/save")
    public MapResult save(@RequestBody ActivitySkuRefSaveRequest request) {
        String validateResult = request.validateParams();
        if (Objects.nonNull(validateResult)) {
            return MapResult.errorResult().setInfo(validateResult);
        }

        // 校验活动状态，如果已经审核通过了就不能再添加商品了
        Activity activity = activityService.queryById(request.getActivityId());
        if (Objects.isNull(activity)) {
            return MapResult.errorResult().setInfo("活动不存在");
        }
        if (activity.getStatus() > ActivityStatusVal.AUDIT_PASS.getCode()) {
            return MapResult.errorResult().setInfo("该活动在当前状态下不允许添加商品");
        }

        // 校验sku是否重复
        Integer count = activitySkuRefService.countByActivityIdAndSkuId(request.getActivityId(), request.getSkuId());
        if (count > 0) {
            return MapResult.errorResult().setInfo("该商品已存在");
        }

        // 调用依赖的商品系统接口锁定商品库存
        if (!productApi.lockStock(request.getSkuId(), request.getSeckillingStock())) {
            return MapResult.errorResult().setInfo("锁定商品库存失败");
        }
        log.info("调用依赖的商品系统锁定商品库存, skuId={}, 锁定的库存={}", request.getSkuId(), request.getSeckillingStock());

        ActivitySkuRef.ActivitySkuRefBuilder builder = ActivitySkuRef.builder();
        // 来自参数的字段值
        builder.activityId(request.getActivityId())
                .skuId(request.getSkuId())
                .price(request.getPrice())
                .seckillingStock(request.getSeckillingStock());
        // 设置字段的初始值
        builder.pageReady(Boolean.FALSE);
        ActivitySkuRef activitySkuRef = builder.build();
        activitySkuRefService.save(activitySkuRef);
        log.info("保存活动和商品之间的关联关系, activitySkuRefId={}", activitySkuRef.getId());
        return MapResult.successResult().set("id", activitySkuRef.getId());
    }

    /**
     * 修改秒杀活动的商品信息
     * 可以修改：展示的原价，秒杀价，秒杀库存，限购数量
     */
    @PutMapping("/modify")
    public MapResult modify(ActivitySkuRefModifyRequest request) {
        String validateResult = request.validateParams();
        if (Objects.nonNull(validateResult)) {
            return MapResult.errorResult().setInfo(validateResult);
        }

        ActivitySkuRef activitySkuRef = activitySkuRefService.queryById(request.getActivitySkuRefId());
        // 校验活动状态，如果已经审核通过了就不能再修改商品了
        Activity activity = activityService.queryById(activitySkuRef.getActivityId());
        if (activity.getStatus() > ActivityStatusVal.AUDIT_PASS.getCode()) {
            return MapResult.errorResult().setInfo("该活动在当前状态下不允许添加商品");
        }

        // 判断库存数量变化，数量增加了就去商品系统锁定库存，库存减少了就去商品系统释放库存
        Integer newSeckillingStock = request.getSeckillingStock();
        if (Objects.nonNull(newSeckillingStock)) {
            Integer oldSeckillingStock = activitySkuRef.getSeckillingStock();
            int difference = Math.abs(newSeckillingStock - oldSeckillingStock);
            boolean result = true;
            if (newSeckillingStock > oldSeckillingStock) {
                 result = productApi.lockStock(activitySkuRef.getSkuId(), difference);
            } else if (newSeckillingStock < oldSeckillingStock) {
                 result = productApi.releaseStock(activitySkuRef.getSkuId(), difference);
            }
            if (!result) {
                return MapResult.errorResult().setInfo("操作库存失败");
            }
        }

        // 最后在修改数据库的记录
        activitySkuRefService.modify(request);
        return MapResult.successResult();
    }

    /**
     * 删除秒杀活动的商品
     */
    @DeleteMapping("/remove")
    public MapResult remove(Long activitySkyRefId) {
        if (Objects.isNull(activitySkyRefId) || activitySkyRefId <= 0) {
            return MapResult.errorResult().setInfo("参数不合法");
        }
        ActivitySkuRef activitySkuRef = activitySkuRefService.queryById(activitySkyRefId);
        // 校验活动状态，如果已经审核通过了就不能再删除商品了
        Activity activity = activityService.queryById(activitySkuRef.getActivityId());
        if (Objects.isNull(activity)) {
            return MapResult.errorResult().setInfo("活动不存在");
        }
        if (activity.getStatus() > ActivityStatusVal.AUDIT_PASS.getCode()) {
            return MapResult.errorResult().setInfo("该活动在当前状态下不允许删除商品");
        }

        // 释放掉库存
        if (!productApi.releaseStock(activitySkuRef.getSkuId(), activitySkuRef.getSeckillingStock())) {
            return MapResult.errorResult().setInfo("操作库存失败");
        }

        activitySkuRefService.remove(activitySkyRefId);
        return MapResult.successResult();
    }

}
